package com.shlh.saas.service.canton.exhibitor.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shlh.saas.entity.canton.exhibitor.*;
import com.shlh.saas.service.canton.exhibitor.CantonFairExhibitorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * 重构后的广交会展商服务实现类
 * 使用策略模式和组合模式来减少代码重复
 */
@Service
@Slf4j
public class CantonFairExhibitorServiceRefactored extends AbstractCantonFairExhibitorService implements CantonFairExhibitorService {

    // 届数处理器映射
    private final Map<String, SessionExhibitorProcessor> sessionProcessors = new HashMap<>();

    @Autowired
    public CantonFairExhibitorServiceRefactored(List<SessionExhibitorProcessor> processors) {
        // 初始化届数处理器映射
        for (SessionExhibitorProcessor processor : processors) {
            sessionProcessors.put(processor.getSessionNumber(), processor);
        }
        log.info("初始化广交会展商服务，支持的届数: {}", sessionProcessors.keySet());
    }

    @Override
    public Page<CantonFairExhibitor127> pageExhibitor127(String companyName, String category, int pageNum, int pageSize) {
        // 这个方法保持原有实现，因为返回类型特定
        SessionExhibitorProcessor processor = sessionProcessors.get("127");
        if (processor == null) {
            throw new IllegalStateException("第127届处理器未找到");
        }
        
        // 计算偏移量
        int offset = (pageNum - 1) * pageSize;
        
        // 使用处理器搜索
        @SuppressWarnings("unchecked")
        List<CantonFairExhibitor127> records = (List<CantonFairExhibitor127>) processor.searchWithFilters(
            companyName, null, category, null, null, null, offset, pageSize);
        
        // 统计总数
        long total = processor.countWithFilters(companyName, null, category, null, null, null);
        
        // 构建分页结果
        Page<CantonFairExhibitor127> page = new Page<>(pageNum, pageSize);
        page.setRecords(records);
        page.setTotal(total);
        
        return page;
    }

    @Override
    public Page<CantonFairExhibitor128> pageExhibitor128(String companyName, String companyType, int pageNum, int pageSize) {
        SessionExhibitorProcessor processor = sessionProcessors.get("128");
        if (processor == null) {
            throw new IllegalStateException("第128届处理器未找到");
        }
        
        int offset = (pageNum - 1) * pageSize;
        
        @SuppressWarnings("unchecked")
        List<CantonFairExhibitor128> records = (List<CantonFairExhibitor128>) processor.searchWithFilters(
            companyName, null,null, companyType, null, null, offset, pageSize);
        
        long total = processor.countWithFilters(companyName, null, null, companyType, null, null);
        
        Page<CantonFairExhibitor128> page = new Page<>(pageNum, pageSize);
        page.setRecords(records);
        page.setTotal(total);
        
        return page;
    }

    @Override
    public Page<CantonFairExhibitor134> pageExhibitor134(String companyName, String industry, int pageNum, int pageSize) {
        SessionExhibitorProcessor processor = sessionProcessors.get("134");
        if (processor == null) {
            throw new IllegalStateException("第134届处理器未找到");
        }
        
        int offset = (pageNum - 1) * pageSize;
        
        @SuppressWarnings("unchecked")
        List<CantonFairExhibitor134> records = (List<CantonFairExhibitor134>) processor.searchWithFilters(
            companyName, null, industry, null, null, null, offset, pageSize);
        
        long total = processor.countWithFilters(companyName, null, industry, null, null, null);
        
        Page<CantonFairExhibitor134> page = new Page<>(pageNum, pageSize);
        page.setRecords(records);
        page.setTotal(total);
        
        return page;
    }

    @Override
    public Page<CantonFairExhibitor135> pageExhibitor135(String companyName, String province, int pageNum, int pageSize) {
        SessionExhibitorProcessor processor = sessionProcessors.get("135");
        if (processor == null) {
            throw new IllegalStateException("第135届处理器未找到");
        }
        
        int offset = (pageNum - 1) * pageSize;
        
        @SuppressWarnings("unchecked")
        List<CantonFairExhibitor135> records = (List<CantonFairExhibitor135>) processor.searchWithFilters(
            companyName, null, null, null, null, null, offset, pageSize);
        
        long total = processor.countWithFilters(companyName, null,  null, null, null, null);
        
        Page<CantonFairExhibitor135> page = new Page<>(pageNum, pageSize);
        page.setRecords(records);
        page.setTotal(total);
        
        return page;
    }

    @Override
    public Page<CantonFairExhibitor136> pageExhibitor136(String companyName, String province, int pageNum, int pageSize) {
        SessionExhibitorProcessor processor = sessionProcessors.get("136");
        if (processor == null) {
            throw new IllegalStateException("第136届处理器未找到");
        }
        
        int offset = (pageNum - 1) * pageSize;
        
        @SuppressWarnings("unchecked")
        List<CantonFairExhibitor136> records = (List<CantonFairExhibitor136>) processor.searchWithFilters(
            companyName, null, null, null, null, null, offset, pageSize);
        
        long total = processor.countWithFilters(companyName, null,  null, null, null, null);
        
        Page<CantonFairExhibitor136> page = new Page<>(pageNum, pageSize);
        page.setRecords(records);
        page.setTotal(total);
        
        return page;
    }

    @Override
    public CantonFairExhibitor127 getExhibitor127ById(Integer id) {
        SessionExhibitorProcessor processor = sessionProcessors.get("127");
        if (processor == null) {
            throw new IllegalStateException("第127届处理器未找到");
        }
        return (CantonFairExhibitor127) processor.getById(id.longValue());
    }

    @Override
    public CantonFairExhibitor128 getExhibitor128ById(Integer id) {
        SessionExhibitorProcessor processor = sessionProcessors.get("128");
        if (processor == null) {
            throw new IllegalStateException("第128届处理器未找到");
        }
        return (CantonFairExhibitor128) processor.getById(id.longValue());
    }

    @Override
    public CantonFairExhibitor134 getExhibitor134ById(Integer id) {
        SessionExhibitorProcessor processor = sessionProcessors.get("134");
        if (processor == null) {
            throw new IllegalStateException("第134届处理器未找到");
        }
        return (CantonFairExhibitor134) processor.getById(id.longValue());
    }

    @Override
    public CantonFairExhibitor135 getExhibitor135ById(Integer id) {
        SessionExhibitorProcessor processor = sessionProcessors.get("135");
        if (processor == null) {
            throw new IllegalStateException("第135届处理器未找到");
        }
        return (CantonFairExhibitor135) processor.getById(id.longValue());
    }

    @Override
    public CantonFairExhibitor136 getExhibitor136ById(Integer id) {
        SessionExhibitorProcessor processor = sessionProcessors.get("136");
        if (processor == null) {
            throw new IllegalStateException("第136届处理器未找到");
        }
        return (CantonFairExhibitor136) processor.getById(id.longValue());
    }

    @Override
    public List<Object> findByCompanyName(String companyName) {
        List<Object> result = new ArrayList<>();
        
        // 遍历所有届数处理器
        for (SessionExhibitorProcessor processor : sessionProcessors.values()) {
            try {
                List<? extends Object> sessionResults = processor.searchWithFilters(
                    companyName, null, null, null, null, null, 0, 100);
                result.addAll(sessionResults);
            } catch (Exception e) {
                log.warn("第{}届展商查询失败", processor.getSessionNumber(), e);
            }
        }
        
        return result;
    }

    @Override
    public List<BaseCantonFairExhibitor> searchByKeywordInAllFields(String keyword, int offset, int limit) {
        return searchWithAllProcessors(keyword, null, null, null, null, null, offset, limit, false);
    }

    @Override
    public long countByKeywordInAllFields(String keyword) {
        return countWithAllProcessors(keyword,  null, null, null, null, null);
    }

    @Override
    public List<BaseCantonFairExhibitor> searchByKeywordInAllFieldsWithFilters(String keyword, String product,
            String sessionInfo, String category, String companyType, String companyScale, String hasContact,
            int offset, int limit) {
        
        // 如果指定了届数，只查询指定届数
        if (StringUtils.hasText(sessionInfo)) {
            return searchWithSpecificSession(sessionInfo, keyword, product, category, companyType, companyScale, hasContact, offset, limit, false);
        }
        
        // 否则查询所有届数
        return searchWithAllProcessors(keyword, product, category, companyType, companyScale, hasContact, offset, limit, false);
    }

    @Override
    public long countByKeywordInAllFieldsWithFilters(String keyword, String product,
            String sessionInfo, String category, String companyType, String companyScale, String hasContact) {
        
        // 如果指定了届数，只统计指定届数
        if (StringUtils.hasText(sessionInfo)) {
            return countWithSpecificSession(sessionInfo, keyword, product, category, companyType, companyScale, hasContact);
        }
        
        // 否则统计所有届数
        return countWithAllProcessors(keyword, product, category, companyType, companyScale, hasContact);
    }

    @Override
    public List<BaseCantonFairExhibitor> searchByKeywordInAllFieldsForExport(String keyword, String product, int offset, int limit) {
        return searchWithAllProcessors(keyword,  product, null, null, null, null, offset, limit, true);
    }

    @Override
    public List<BaseCantonFairExhibitor> searchByKeywordInAllFieldsWithFiltersForExport(String keyword, String product,
            String sessionInfo, String category, String companyType, String companyScale, String hasContact,
            int offset, int limit) throws ExecutionException, InterruptedException {
        
        // 如果指定了届数，只查询指定届数
        if (StringUtils.hasText(sessionInfo)) {
            return searchWithSpecificSession(sessionInfo, keyword, product, category, companyType, companyScale, hasContact, offset, limit, true);
        }
        
        // 否则查询所有届数
        return searchWithAllProcessors(keyword, product, category, companyType, companyScale, hasContact, offset, limit, true);
    }

    @Override
    public String getFullContactInfo(Long exhibitorId, Integer sessionNumber, String fieldName) {
        SessionExhibitorProcessor processor = sessionProcessors.get(sessionNumber.toString());
        if (processor == null) {
            throw new IllegalArgumentException("不支持的届数: " + sessionNumber);
        }
        
        return processor.getFieldValue(exhibitorId, fieldName);
    }

    /**
     * 使用所有处理器进行搜索
     */
    private List<BaseCantonFairExhibitor> searchWithAllProcessors(String keyword, String product, String category,
            String companyType, String companyScale, String hasContact, int offset, int limit, boolean forExport) {
        
        List<BaseCantonFairExhibitor> result = new ArrayList<>();
        
        // 按届数顺序处理
        List<String> sortedSessions = sessionProcessors.keySet().stream()
            .sorted(Collections.reverseOrder()) // 从最新届数开始
            .collect(Collectors.toList());
        
        int remaining = limit;
        int currentOffset = offset;
        
        for (String sessionNumber : sortedSessions) {
            if (remaining <= 0) break;
            
            SessionExhibitorProcessor processor = sessionProcessors.get(sessionNumber);
            try {
                // 先统计该届数的总数
                long sessionCount = processor.countWithFilters(keyword, product, category, companyType, companyScale,hasContact);
                
                if (currentOffset < sessionCount) {
                    // 需要从该届数中查询数据
                    int sessionLimit = (int) Math.min(remaining, sessionCount - currentOffset);
                    List<? extends Object> sessionResults = processor.searchWithFilters(
                        keyword, product, category, companyType, companyScale, hasContact, currentOffset, sessionLimit);
                    
                    // 转换为BaseCantonFairExhibitor
                    for (Object exhibitor : sessionResults) {
                        BaseCantonFairExhibitor baseExhibitor = forExport ? 
                            processor.convertToBaseForExport(exhibitor) : 
                            processor.convertToBase(exhibitor);
                        if (baseExhibitor != null) {
                            result.add(baseExhibitor);
                        }
                    }
                    
                    remaining -= sessionResults.size();
                    currentOffset = 0; // 后续届数从0开始
                } else {
                    // 跳过该届数
                    currentOffset -= (int) sessionCount;
                }
                
            } catch (Exception e) {
                log.warn("第{}届展商搜索失败", sessionNumber, e);
            }
        }
        
        return result;
    }

    /**
     * 使用所有处理器进行统计
     */
    private long countWithAllProcessors(String keyword, String product, String category, String companyType, String companyScale, String hasContact) {
        long total = 0;
        
        for (SessionExhibitorProcessor processor : sessionProcessors.values()) {
            try {
                total += processor.countWithFilters(keyword, product, category, companyType, companyScale, hasContact);
            } catch (Exception e) {
                log.warn("第{}届展商统计失败", processor.getSessionNumber(), e);
            }
        }
        
        return total;
    }

    /**
     * 使用指定届数处理器进行搜索
     */
    private List<BaseCantonFairExhibitor> searchWithSpecificSession(String sessionInfo, String keyword, String product,
            String category, String companyType, String companyScale, String hasContact, int offset, int limit, boolean forExport) {
        
        // 提取届数
        String sessionNumber = extractSessionNumber(sessionInfo);
        SessionExhibitorProcessor processor = sessionProcessors.get(sessionNumber);
        
        if (processor == null) {
            log.warn("不支持的届数: {}", sessionInfo);
            return new ArrayList<>();
        }
        
        List<BaseCantonFairExhibitor> result = new ArrayList<>();
        
        try {
            List<? extends Object> sessionResults = processor.searchWithFilters(
                keyword, product, category, companyType, companyScale, hasContact, offset, limit);
            
            for (Object exhibitor : sessionResults) {
                BaseCantonFairExhibitor baseExhibitor = forExport ? 
                    processor.convertToBaseForExport(exhibitor) : 
                    processor.convertToBase(exhibitor);
                if (baseExhibitor != null) {
                    result.add(baseExhibitor);
                }
            }
            
        } catch (Exception e) {
            log.error("第{}届展商搜索失败", sessionNumber, e);
        }
        
        return result;
    }

    /**
     * 使用指定届数处理器进行统计
     */
    private long countWithSpecificSession(String sessionInfo, String keyword, String product,
            String category, String companyType, String companyScale, String hasContact) {
        
        String sessionNumber = extractSessionNumber(sessionInfo);
        SessionExhibitorProcessor processor = sessionProcessors.get(sessionNumber);
        
        if (processor == null) {
            log.warn("不支持的届数: {}", sessionInfo);
            return 0;
        }
        
        try {
            return processor.countWithFilters(keyword, product, category, companyType, companyScale, hasContact);
        } catch (Exception e) {
            log.error("第{}届展商统计失败", sessionNumber, e);
            return 0;
        }
    }

    /**
     * 从届数信息中提取届数数字
     */
    private String extractSessionNumber(String sessionInfo) {
        if (!StringUtils.hasText(sessionInfo)) {
            return "";
        }
        
        // 提取数字
        String number = sessionInfo.replaceAll("[^0-9]", "");
        return number;
    }
}
